//Copyright  2015 Max "Shrinker" Wieden
//Refer to license for license details.

//this grammar matches Quake 3 MAP files
//trained with a quick test with GTKRadiant 1.6.4
Tokens:
	FloatLiteral         = [['+', '-']] (BaseFloatLiteral [FloatExponent] | NumericLiteral FloatExponent);
	#FloatExponent       = ['E', 'e'] [['+', '-']] (Digit)+;
	IntLiteral           = [['+', '-']] NumericLiteral;
	Name                 = FirstNameChar (FirstNameChar | Digit)+ | SimpleFirstNameChar;
	LBrace               = '{';
	LBracket             = '[';
	LPar                 = '(';
	RBrace               = '}';
	RBracket             = ']';
	RPar                 = ')';
	StringLiteral        = '\"' (~['\"'])* '\"';
	#FirstNameChar       = SimpleFirstNameChar | ['+', '-', '{'];
	#Digit               = ['0'-'9'];
	#SimpleFirstNameChar = ['A'-'Z'] | ['a'-'z'] | ['!', '#', '_', '/', '~'];
	#NumericLiteral      = '0' | ['1'-'9'] (Digit)*;
	#BaseFloatLiteral    = (Digit)+ '.' (Digit)* | '.' (Digit)+;

FillerTokens:
	SingleLineComment = "//" (~['\r', '\n'])* ["\r\n" | ['\r', '\n']];
	Whitespace        = (['\t', ' ', '\r', '\n'])+;

TokenSpecializations:
	KeyPatchDef2 = Name("patchDef2");

Rules:
Start = {
	(Entity)*
	EOF
}

Entity = {
	LBrace
	(KeyValuePair)+
	(Solid       )*
	RBrace
}

Solid = {
	LBrace
	(
		PatchDef
	|	(Side)*
	)
	RBrace
}

PatchDef = {
	KeyPatchDef2
	LBrace
	TextureName
	LPar (IntLiteral | FloatLiteral)+ RPar
	LPar (PatchDefColumn           )+ RPar
	RBrace
}

PatchDefColumn = {
	LPar (PatchDefAnchor)+ RPar
}

PatchDefAnchor = {
	LPar (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) RPar
}

Side = {
	LPar (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) RPar
	LPar (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) RPar
	LPar (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) RPar
	TextureName
	(IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral)
	(IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral) (IntLiteral | FloatLiteral)
}

KeyValuePair = {StringLiteral StringLiteral}

TextureName = {
	Name | KeyPatchDef2
}
